﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Web.Script.Serialization;
using Loki.Utils;
using Luna.Connectors.Google;
using Luna.Connectors.ZohoCRM;
using Luna.Data.Configuration;
using Luna.Model;

namespace Luna.Connectors
{
    internal abstract class ConnectorConfiguration : LunaEntity<IConnectorData>, IConnectorConfiguration
    {
        #region Type

        public abstract ConnectorType Type
        {
            get;
        }

        #endregion Type

        #region Name

        private static PropertyChangedEventArgs _NameChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorConfiguration>(x => x.Name);

        private static PropertyChangingEventArgs _NameChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorConfiguration>(x => x.Name);

        private string _Name;

        public string Name
        {
            get
            {
                return _Name;
            }

            set
            {
                if (value != _Name)
                {
                    NotifyChanging(_NameChangingArgs);
                    _Name = value;
                    NotifyChanged(_NameChangedArgs);
                }
            }
        }

        #endregion Name

        #region Enabled

        private static PropertyChangedEventArgs _EnabledChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorConfiguration>(x => x.Enabled);

        private static PropertyChangingEventArgs _EnabledChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorConfiguration>(x => x.Enabled);

        private bool _Enabled;

        public bool Enabled
        {
            get
            {
                return _Enabled;
            }

            set
            {
                if (value != _Enabled)
                {
                    NotifyChanging(_EnabledChangingArgs);
                    _Enabled = value;
                    NotifyChanged(_EnabledChangedArgs);
                }
            }
        }

        #endregion Enabled

        #region Login

        private static PropertyChangedEventArgs _LoginChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorConfiguration>(x => x.Login);

        private static PropertyChangingEventArgs _LoginChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorConfiguration>(x => x.Login);

        public string Login
        {
            get
            {
                return Data.Login;
            }

            set
            {
                if (value != Data.Login)
                {
                    NotifyChanging(_LoginChangingArgs);
                    Data.Login = value;
                    NotifyChangedAndDirty(_LoginChangedArgs);
                }
            }
        }

        #endregion Login

        #region Password

        private static PropertyChangedEventArgs _PasswordChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorConfiguration>(x => x.Password);

        private static PropertyChangingEventArgs _PasswordChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorConfiguration>(x => x.Password);

        public string Password
        {
            get
            {
                return Data.Password;
            }

            set
            {
                if (value != Data.Password)
                {
                    NotifyChanging(_PasswordChangingArgs);
                    Data.Password = value;
                    NotifyChangedAndDirty(_PasswordChangedArgs);
                }
            }
        }

        #endregion Password

        #region Parameters

        private Dictionary<string, string> _Parameters;

        public IDictionary<string, string> Parameters
        {
            get { return _Parameters; }
        }

        #endregion Parameters

        protected ConnectorConfiguration(IConnector P_Connector, IConnectorData P_Data)
            : base(P_Data)
        {
            Name = P_Connector.Name;
            Enabled = P_Connector.Enabled;
            LoadParameters();
        }

        protected ConnectorConfiguration(IConnector P_Connector)
        {
            Name = P_Connector.Name;
            Enabled = P_Connector.Enabled;
            _Parameters = new Dictionary<string, string>();
        }

        #region Parameters serialisation

        private JavaScriptSerializer _Serializer = new JavaScriptSerializer();

        protected void LoadParameters()
        {
            if (string.IsNullOrEmpty(Data.Params))
            {
                _Parameters = new Dictionary<string, string>();
            }
            else
            {
                _Parameters = _Serializer.Deserialize<Dictionary<string, string>>(Data.Params);
            }
        }

        protected void SaveParameters()
        {
            if (_Parameters.Count == 0)
            {
                Data.Params = null;
            }
            else
            {
                Data.Params = _Serializer.Serialize(_Parameters);
            }
        }

        #endregion Parameters serialisation

        public static IConnectorConfiguration Create(IConnector P_Connector)
        {
            switch (P_Connector.Type)
            {
                case ConnectorType.Google:
                    return new GoogleConfiguration(P_Connector);

                case ConnectorType.ZohoCRM:
                    return new ZohoCRMConfiguration(P_Connector);

                default:
                    return null;
            }
        }

        public static IConnectorConfiguration Create(IConnector P_Connector, IConnectorData P_Data)
        {
            switch (P_Connector.Type)
            {
                case ConnectorType.Google:
                    return new GoogleConfiguration(P_Connector, P_Data);

                case ConnectorType.ZohoCRM:
                    return new ZohoCRMConfiguration(P_Connector, P_Data);

                default:
                    return null;
            }
        }
    }
}